package com.joysuch.wwyt.bp.service.impl;

import cn.zlg.common.datadump.bean.BatchDeleteResult;
import com.joysuch.wwyt.bp.entity.BPNFCLocation;
import com.joysuch.wwyt.bp.entity.dsl.QBPNFCLocation;
import com.joysuch.wwyt.bp.entity.inspect.BPInspectPoint;
import com.joysuch.wwyt.bp.repository.BPInspectPointRepository;
import com.joysuch.wwyt.bp.repository.BPNFCLocationDao;
import com.joysuch.wwyt.bp.service.BPInspectPointService;
import com.joysuch.wwyt.bp.service.BpNFCLocationService;
import com.joysuch.wwyt.core.bean.BaseAddNfcCardBean;
import com.joysuch.wwyt.core.bean.BaseNfcCardBean;
import com.joysuch.wwyt.core.bean.BaseSearchNfcCardBean;
import com.joysuch.wwyt.core.common.util.PageDataUtils;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Predicate;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Service
@Slf4j
@Transactional
public class BPNFCLocationServiceImpl implements BpNFCLocationService {

    @Autowired
    private BPNFCLocationDao bpnfcLocationDao;
    @Autowired
    private BPInspectPointRepository bpInspectPointDao;


    @Override
    public List<BPNFCLocation> findAll() {
        return bpnfcLocationDao.findAll();
    }

    /**
     * 新增NFC卡
     *
     * @param bean
     * @return
     */
    @Override
    public BPNFCLocation add(BaseNfcCardBean bean) {
        checkNameAndCode(bean);
        BPNFCLocation card = new BPNFCLocation();
        card.setCode(bean.getCode());
        card.setName(bean.getName());
        card.setLocation(StringUtils.isEmpty(bean.getLocation()) ? null : bean.getLocation());
        return bpnfcLocationDao.save(card);
    }

    /**
     * 修改NFC卡
     *
     * @param bean
     * @return
     */
    @Override
    public BPNFCLocation update(BaseNfcCardBean bean) {
        Optional<BPNFCLocation> bf = bpnfcLocationDao.findById(bean.getId());
        if (!bf.isPresent()) {
            throw new IllegalArgumentException("数据不存在");
        }
        BPNFCLocation card = bf.get();
        card.setId(bean.getId());
        card.setName(bean.getName());
        card.setCode(bean.getCode());
        card.setLocation(StringUtils.isEmpty(bean.getLocation()) ? null : bean.getLocation());
        BPNFCLocation location = bpnfcLocationDao.save(card);
        //NFC卡 编码,名称唯一性判断
        if (location.getCode() != null) {
            List<BPNFCLocation> l = bpnfcLocationDao.findByCode(location.getCode());
            if (l != null && l.size() > 1) {
                throw new IllegalArgumentException("NFC卡识别码已存在");
            }
        }

        if (location.getName() != null) {
            List<BPNFCLocation> l = bpnfcLocationDao.findByName(location.getName());
            if (l != null && l.size() > 1) {
                throw new IllegalArgumentException("NFC卡名称已存在");
            }
        }

        return location;
    }

    /**
     * 查询NFC卡
     *
     * @param id
     * @return
     */
    @Override
    public BaseNfcCardBean findById(Long id) {
        Optional<BPNFCLocation> bf = bpnfcLocationDao.findById(id);
        if (!bf.isPresent()) {
            throw new IllegalArgumentException("数据不存在");
        }
        BPNFCLocation card = bf.get();
        BaseNfcCardBean bean = new BaseNfcCardBean();
        bean.setId(card.getId());
        bean.setCode(card.getCode());
        bean.setName(card.getName());
        bean.setLocation(card.getLocation());
        return bean;
    }

    public BaseNfcCardBean getById(Long id) {
        Optional<BPNFCLocation> bf = bpnfcLocationDao.findById(id);
        if (!bf.isPresent()) {
            return null;
        }
        BPNFCLocation card = bf.get();
        BaseNfcCardBean bean = new BaseNfcCardBean();
        bean.setId(card.getId());
        bean.setCode(card.getCode());
        bean.setName(card.getName());
        bean.setLocation(card.getLocation());
        return bean;
    }


    /**
     * 删除NFC卡
     *
     * @param id
     */
    @Override
    public void deleteCard(Long id) {
        BPNFCLocation card = bpnfcLocationDao.findById(id).orElseThrow(() -> new IllegalArgumentException("定位卡不存在"));
        List<BPInspectPoint> points = bpInspectPointDao.findByInspectLocationAndLocationType(card.getCode(), "NFC");
        if (!CollectionUtils.isEmpty(points)) {
            throw new IllegalArgumentException("NFC卡(" + card.getName() + ")已被检查点绑定,请先解除绑定关系再删除");
        }
        bpnfcLocationDao.deleteById(id);
    }

    @Override
    public BatchDeleteResult batchNfcDelate(List<Long> ids) {
        int count = 0;
        List<String> message = new ArrayList<>();
        for (Long id : ids) {
            try {
                deleteCard(id);
            } catch (IllegalArgumentException e) {
                message.add(e.getMessage());
                e.printStackTrace();
                count++;
            } catch (Exception ex) {
                message.add("id:" + ex.getMessage());
                log.error(ex.getMessage(), ex);
                count++;
            }
        }
        return BatchDeleteResult.create(ids.size(), ids.size() - count, message);
    }

    @Override
    public BaseNfcCardBean findByCode(String code) {
        BPNFCLocation card = bpnfcLocationDao.findFirstByCode(code);
        if (card == null) {
            throw new IllegalArgumentException("NFC卡不存在");
        }
        BaseNfcCardBean bean = new BaseNfcCardBean();
        bean.setId(card.getId());
        bean.setCode(card.getCode());
        bean.setName(card.getName());
        bean.setLocation(card.getLocation());
        return bean;
    }

    /**
     * 批量新增NFC卡
     *
     * @param bean
     * @return
     */
    @Override
    public List<BPNFCLocation> addList(BaseAddNfcCardBean bean) {
        List<BaseNfcCardBean> list = bean.getList();
        List<BPNFCLocation> cList = new ArrayList<>();
        if (list != null && list.size() > 0) {
            for (BaseNfcCardBean cBean : list) {
                BPNFCLocation card = this.add(cBean);
                cList.add(card);
            }
        }
        return cList;
    }

    /**
     * 分页查询
     *
     * @param page
     * @param condition
     * @return
     */
    @Override
    public Page<BaseNfcCardBean> pageCard(Pageable page, BaseSearchNfcCardBean condition) {
        page = PageDataUtils.addOrderByDesc(page, "id");
        Predicate predicate = prepareListSearchCondition(condition);
        Page<BPNFCLocation> data = predicate == null ? bpnfcLocationDao.findAll(page) : bpnfcLocationDao.findAll(predicate, page);
        return PageDataUtils.convertPageData(data, new PageDataUtils.PageDataConvert<BaseNfcCardBean, BPNFCLocation>() {
            @Override
            public BaseNfcCardBean convert(BPNFCLocation baseConfig) {
                BaseNfcCardBean bean = new BaseNfcCardBean();
                BeanUtils.copyProperties(baseConfig, bean);
                return bean;
            }
        });
    }

    private Predicate prepareListSearchCondition(BaseSearchNfcCardBean condition) {
        Predicate p = null;
        QBPNFCLocation q = QBPNFCLocation.BPNFCLocation;
        if (condition.getNameOrCode() != null) {
            p = ExpressionUtils.and(p, ExpressionUtils.or(q.code.contains(condition.getNameOrCode()),
                    q.name.contains(condition.getNameOrCode())));
        }
        if (condition.getCode() != null) {
            p = ExpressionUtils.and(p, q.code.contains(condition.getCode()));
        }
        if (condition.getName() != null) {
            p = ExpressionUtils.and(p, q.name.contains(condition.getName()));
        }
        if (condition.getSettingArea() != null) {
            if (condition.getSettingArea().intValue() == 1) {
                p = ExpressionUtils.and(p, q.location.isNotNull());
            } else {
                p = ExpressionUtils.and(p, q.location.isNull());
            }
        }
        return p;
    }

    private void checkNameAndCode(BaseNfcCardBean bean) {
        if (bean.getCode() != null) {
            List<BPNFCLocation> l = bpnfcLocationDao.findByCode(bean.getCode());
            if (l != null && l.size() > 0) {
                throw new IllegalArgumentException("NFC卡识别码已存在");
            }
        }

        if (bean.getName() != null) {
            List<BPNFCLocation> l = bpnfcLocationDao.findByName(bean.getName());
            if (l != null && l.size() > 0) {
                throw new IllegalArgumentException("NFC卡名称已存在");
            }
        }
    }

}
